import axios from 'axios';
import {Message} from "element-ui";
import RSA from '../encrypt/rsa';
import AES from '../encrypt/aes';
import store from '../../store'

//输出通用axios实例
const request = axios.create({
    //timeout: 5000,//设置axios请求超时时间
    headers: {
        "Content-Type": "application/json;charset=utf-8"
    },
    withCredentials: true
})

/**
 * 当出错的时候执行的是：Promise.resolve(err);，而不是Promise.reject(err);
 * 这是什么原因呢？因为封装axios一个重要的目的就是希望能够对错误进行统一处理，不用在每一次发起网络请求的时候都去处理各种异常情况，将所有的异常情况都在工具js中进行统一的处理。
 * 但是这种方式也带来一个问题，就是在发起网络请求的时候，一般都会开启一个进度条，当网络请求结束时，不论请求成功还是失败，都要将这个进度条关闭掉，而失败的处理都统一写在工具js里边了，
 * 因此就没在请求失败时关闭进度条了，解决这个问题，有两种方案：
 * 1.直接在request的拦截器中开启一个fullscreen的loading，然后在response的拦截器中将其关闭，即将进度条也封装到工具js中了，但是非常不推荐这种方式，因为这种方式的用户体验非常之差，有兴趣的小伙伴可以自己试一下就知道了。
 * 2.第二种解决方案就是大家看到的，返回一个Promise.resolve(err)，则这个请求不会就此结束，错误的message已经弹出来了，但是这条消息还是会继续传到then中，也就是说，无论请求成功还是失败，在成功的回调中都能收到通知，
 * 这样就可以将loading关闭了
 */

/**
 * 获取前端RSA公钥密码、AES的key
 * @type {any}
 */
let genKeyPair = RSA.genKeyPair();
let publicKey = genKeyPair.publicKey;
let privateKey = genKeyPair.privateKey;

request.interceptors.request.use(config => {
    //加密再传输
    if(config.method.toLowerCase() == "post") {
        let data = config.data;
        //发送请求之前随机获取AES的key
        let aesKey = AES.genKey();
        // data = {
        //     data: AES.encrypt(data, aesKey),//AES加密后的数据
        //     aesKey: RSA.encrypt(aesKey, store.getters.getPublicKey),//后端RSA公钥加密后的AES的key
        //     publicKey: publicKey //前端公钥
        // };
        let form = new FormData();
        form.append("data", AES.encrypt(data, aesKey));
        form.append("aesKey", RSA.encrypt(aesKey, store.getters.getPublicKey));
        form.append("publicKey", publicKey);
        config.data = form;
        config.headers = {
            'Content-Type': 'application/x-www-form-urlencoded'
        };
    }
    return config;
}, error => {
    Message.error({message: '请求超时!'});
    return Promise.resolve(error);
})

request.interceptors.response.use(result => {
    if(result.config.method.toLowerCase() == "post") {
        let data = result.data.data.result;
        data = AES.decrypt(data.data, RSA.decrypt(data.aesKey, privateKey));
        result.data.data = data;
    }
    if (result.status && result.status == 200 && result.data.status == 'success') {
        Message.error({message: result.data.msg});
        return;
    }
    return result;
}, error => {
    if (error.response.status == 504 || error.response.status == 404) {
        Message.error({message: '服务器被吃了⊙﹏⊙∥'});
    } else if (error.response.status == 403) {
        Message.error({message: '权限不足,请联系管理员!'});
    } else {
        Message.error({message: '未知错误!'});
    }
    return Promise.resolve(error);
})

// 导出自定义创建的axios对象
export default request
